package com.zn.loading
{
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.net.URLVariables;
    

    public class LoaderMax extends LoaderItem
    {
        public static var loaderNameList:Object = {};

        public static var loaderURLList:Object = {};

        private var _childLoader:Array = [];

        private var currentLoaderItem:LoaderItem;

        private var _childLoadIndex:int = 0;

        private static var _cacheID:Number = new Date().time;

        public static var noCache:Boolean = true;

        private var _loaderItemList:Array = [];

		
        public function LoaderMax(name:String = null)
        {
            super(null, name);
        }

        public static function activeLoader(list:Array):void
        {

        }

        public function addChildLoad(loaderItem:LoaderItem):void
        {
            _childLoader.push(loaderItem);
        }

        public override function load(flush:Boolean = false):void
        {
			loaderStatus = LoaderStatus.LOADING;
            _loaderItemList = getLoaderItemList();
			
			_childLoadIndex = 0;
            _bytesTotal = 0;
            _bytesLoaded = 0;
			loadNext();			
        }
		
        public function getLoaderItemList():Array
		{
            var count:int = 0;
			
			var item:LoaderItem;
            var list:Array = [];
			for (var i:int = 0; i < _childLoader.length; i++) 
			{
                item = _childLoader[i];
                if (item is LoaderMax)
                    list = list.concat((item as LoaderMax).getLoaderItemList());
				else
                    list.push(item)
			}
			
            return list;
		}
		
        protected function childCompelteHandler(event:Event):void
        {
            loadNext();
        }

        protected function childIoErrorHandler(event:Event):void
        {
            //loadNext();
			loaderStatus  = LoaderStatus.FAILED;
			trace(LoaderItem,"ioErrorHandler", name);
			dispatchEvent(new LoaderEvent(LoaderEvent.IO_ERROR,this));
        }

        protected function childProgressHandler(event:Event):void
        {
            _bytesLoaded = currentLoaderItem.bytesLoaded;
            _bytesTotal = currentLoaderItem.bytesTotal;

            updateCurrentProgress();
        }

        protected function loadNext():void
        {
			removeCurrentLoaderItemEvent();

            if (_childLoadIndex >= _loaderItemList.length)
            {
                _childLoadIndex = _loaderItemList.length;
				
				loaderStatus = LoaderStatus.COMPLETED;
                dispatchEvent(new LoaderEvent(LoaderEvent.COMPLETE, this, 1, 1, _childLoadIndex, _loaderItemList.length));
                return;
            }

            currentLoaderItem = _loaderItemList[_childLoadIndex];
			
            if (currentLoaderItem.loaderStatus == LoaderStatus.COMPLETED)
			{
                _childLoadIndex++;
                updateCurrentProgress();
				
				loadNext();
                return;
			}
			
            currentLoaderItem.addEventListener(LoaderEvent.COMPLETE, childCompelteHandler, false, 0, true);
            currentLoaderItem.addEventListener(LoaderEvent.IO_ERROR, childIoErrorHandler, false, 0, true);
            currentLoaderItem.addEventListener(LoaderEvent.PROGRESS, childProgressHandler, false, 0, true);
			
            if (currentLoaderItem.loaderStatus == LoaderStatus.LOADING)
			{
				
				_childLoadIndex++;
                updateCurrentProgress();
                return;
			}
			
			
            _childLoadIndex++;
            updateCurrentProgress();
            currentLoaderItem.load();
        }

        private function updateCurrentProgress():void
        {
            dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS, this, _bytesLoaded, _bytesTotal, _childLoadIndex, _loaderItemList.length));
        }

		private function removeCurrentLoaderItemEvent():void
		{
			if (currentLoaderItem)
			{
			    currentLoaderItem.removeEventListener(LoaderEvent.COMPLETE, childCompelteHandler);
			    currentLoaderItem.removeEventListener(LoaderEvent.IO_ERROR, childIoErrorHandler);
			    currentLoaderItem.removeEventListener(LoaderEvent.PROGRESS, childProgressHandler);
			    currentLoaderItem = null;
			}
		}


        public static function getLoader(name:String):LoaderItem
        {
            return loaderNameList[name] ? loaderNameList[name] : loaderURLList[name];
        }

        public static function getContent(name:String):Object
        {
            var loader:LoaderItem = getLoader(name);

            return loader ? loader.content : null;
        }

        public static function addLoaderItem(loaderItem:LoaderItem):void
        {
            if (loaderItem.name)
                loaderNameList[loaderItem.name] = loaderItem;

            if (loaderItem.url)
                loaderURLList[loaderItem.url] = loaderItem;
        }

        public static function removeLoaderItem(name:String, unloader:Boolean = true):void
        {
            if (name)
            {
                if (unloader)
                {
                    var loader:LoaderItem = LoaderItem(loaderNameList[name]);
                    loader.unload();
                }
                delete loaderNameList[name];
                delete loaderURLList[name];
            }
        }
		
		public override function stop():void
		{
			super.stop();
			
            if (currentLoaderItem)
				currentLoaderItem.stop();
			
			removeCurrentLoaderItemEvent();
		}

		public override function pause():void
		{
			super.pause();
			
			if (currentLoaderItem)
				currentLoaderItem.pause();
		}		

        /**
         *获取一个不会缓存的加载请求
         * @param url
         * @return
         *
         */
        public static function getNoCacheURLRequest(url:String):URLRequest
        {
            var urlRequest:URLRequest = new URLRequest(url);
            setRequestURL(urlRequest, url, "cacheID=" + _cacheID);

            return urlRequest;
        }
		
		/**
		 *根据版本号获取加载请求 
		 * @param url
		 * @return 
		 * 
		 */
        public static function getURLRequestByVersion(url:String, version:uint):URLRequest
		{
			var urlRequest:URLRequest = new URLRequest(url);
			setRequestURL(urlRequest, url, "version=" + version);
			
			return urlRequest;
		}
		
		/**
		 *获取加载请求 
		 * @return 
		 * 
		 */
        public static function getURLRequest(url:String, hasNoCache:Boolean = false, version:int = -1):URLRequest
		{
			var urlRequest:URLRequest;
			
            if (noCache)
				return getNoCacheURLRequest(url);
			
            if (hasNoCache && noCache)
                urlRequest = getNoCacheURLRequest(url);
			else if (version != -1)
                urlRequest = getURLRequestByVersion(url, version);
			else
                urlRequest = new URLRequest(url);
				
			return urlRequest;
		}

        /**
         *设置加载参数
         * @param request
         * @param url
         * @param extraParams
         *
         */
        public static function setRequestURL(request:URLRequest, url:String, extraParams:String = ""):void
        {
            var a:Array = url.split("?");

            var s:String = a[0];
            var parsedURL:String = "";
            for (var i:int = 0; i < s.length; i++)
            {
                parsedURL += s.charAt(i);
            }

            request.url = parsedURL;

            if (!extraParams)
                extraParams = "";

            if (a.length >= 2)
            {
                extraParams += (extraParams == "") ? a[1] : "&" + a[1];
            }
            if (extraParams != "")
            {
                var data:URLVariables = (request.data == null) ? new URLVariables() : request.data as URLVariables;
                a = extraParams.split("&");
                i = a.length;
                var pair:Array;
                while (--i > -1)
                {
                    pair = a[i].split("=");
                    data[pair.shift()] = pair.join("=");
                }
                request.data = data;
            }
        }

		public function get loadrCount():int
		{
            return _childLoadIndex;
		}

		public function get loaderTotalCount():int
		{
			return _loaderItemList.length;
		}

		public static function createLoader(name:String):LoaderItem
		{
			var loaderItem:LoaderItem;
			if (name.search(".png")!=-1)
				loaderItem = new ImageLoader(name);
			else if (name.search(".swf")!=-1)
				loaderItem = new SWFLoader(name);
			else if (name.search(".zip")!=-1)
				loaderItem = new ZipLoader(name);
			else if (name.search(".xml")!=-1)
				loaderItem = new XMLLoader(name);
			
			return loaderItem;
		}
    }
}